package com.corejsf;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
//import org.jboss.security.auth.spi.Users;

/**
 * Configures your user, credentials, and keeps the users in a List.
 *
 * @author Vukasin Simic
 * @version 1.0
 */

@Named("usermanager")
@ApplicationScoped
public class UserManager implements Serializable {

    /**
     * Serial Version ID.
     */
    private static final long serialVersionUID = -5129814544398510305L;

    /**
     * Injecting configurations.
     */
    @Inject private Configurations configs;

    /**
     * Injecting credentials.
     */
    @Inject private Credentials credentials;

    /**
     * List of created users.
     */
    private static List<User> users = new ArrayList<User>();

    /**
     * The count of how many employees have existed in the user list.
     *
     * Used to generate employee numbers.
     */
    private int employeeCount = 0;

    /**
     * No parameter constructor.
     */
    public UserManager() {
    }

    /**
     * Adding initial superuser and adds some non admin users.
     */
    @PostConstruct
    public void addAdmin() {
        String username = configs.getConfig("adminUserName");
        String password = configs.getConfig("adminPassword");
        users.add(new User(username, "Min", "Ad",
            password, true, employeeCount));
        users.add(new User("mp", "Pink", "Mr",
            "mp", false, ++employeeCount));
        users.add(new User("mw", "White", "Mr",
            "mw", false, ++employeeCount));
        users.add(new User("mb", "Brown", "Mr",
            "mb", false, ++employeeCount));
        users.add(new User("mo", "Orange", "Mr",
            "mo", false, ++employeeCount));
    }

    /**
     * Passes username and password to be used by user validation method.
     *
     * @param username to be authenticated
     * @param password to be authenticated
     * @return user or null.
     */
    public User login(final String username, final String password) {
        User user = usernameExists(users, username);
        if (user != null) {
            if (user.getPassword().equals(password)) {
                return user;
            }
        }
        return null;
    }

    /**
     * Checks if the username exists in the list of users.
     *
     * @param list of existing user accounts
     * @param username to be checked for uniqueness among existing user accounts
     * @return User or null
     */
    public User usernameExists(final List<User> list, final String username) {
        for (User user: users) {
            if (user.getUserName().equals(username)) {
                return user;
            }
        }
        return null;
    }

    /**
     * Adds a user from the add user button.
     *
     * @return navigation outcome string
     */
    public String addUser() {
        String proposedUsername = credentials.getUsername();
        if (usernameExists(users, proposedUsername) == null) {
            employeeCount++;
            users.add(new User(credentials.getUsername(),
                credentials.getLastName(), credentials.getFirstName(),
                credentials.getPassword(),
                credentials.isAdmin(), employeeCount));

            return "success";
        }
        return "failure";
    }

    /**
     * Deleting a user using the button in the UI.
     *
     * @param userToDelete from existing user accounts
     * @return null in lieu of navigation outcome string to prompt refresh
     */
    public String deleteRow(final User userToDelete) {
        users.remove(userToDelete);
        return null;
     }

    /**
     * Gets credentials.
     *
     * @return credentials.
     */
    public Credentials getCredentials() {
        return credentials;
    }

    /**
     * Sets a user's credentials.
     *
     * @param credentials entered by user into form
     */
    public void setCredentials(final Credentials credentials) {
        this.credentials = credentials;
    }

    /**
     * Gets a list of users.
     *
     * @return users
     */
    public List<User> getUsers() {
        return users;
    }

    /**
     * Saves the changes made after editing a user.
     *
     * @return null in lieu of navigation outcome string to prompt refresh
     */
    public String save() {
        for (User user : users){
            user.setEditable(false);
        }
        return null;
    }

}
